-- 时间估算
-- 1.搞懂Lua基本语法	 80min
-- 2.算法				40min
-- 3.整理				20min
-- 4.测试				15min
--父类
Shape = {length = 0, width = 0, name = "unknown", S = 0, privateS = "private",
            privateList = {"privateS"}--私有成员key
        }
function Shape:caculateS()
    self.S = self.length * self.width
end

--构造
function Shape:new(o)
    local o = o or {}
    setmetatable(o, {__index = self})--Shape作为模板
    return o
end

shape1 = Shape:new{length = 1, width = 2}--实例一个对象
--重定义shape1函数
function shape1:caculateS()
    self.S = self.length * self.width / 2
end
shape2 = Shape:new{length = 1, width = 2}

shape1:caculateS()
shape2:caculateS()
print("shape1:", shape1.S)
print("shape2:", shape2.S)

--继承
function Shape:inherit(o)
    o = o or {}

    --排除私有变量
    function search(k, class)
        for i = 1, #(class.privateList) do
            if(k == class.privateList[i]) then
                return nil
            end
        end
        return class[k]
    end

    setmetatable(o, {__index = function (t, k)
            local v = search(k, Shape)
            assert(v ~= nil, "No rights")
            return v
        end
    })
    return o
end

--Square 继承 shape
Square = Shape:inherit()

-- print(Square.privateS)    --出现错误，No right

function Square:new(o)
    local o = o or {}
    setmetatable(o, {__index = self})
    o.width = o.length
    return o
end

square = Square:new{name = "Square", length = 2}

square:caculateS()
print("square:", square.S)

--Triangle 继承 shape
Triangle = Shape.inherit()

function Triangle:new(o)
    local o = o or {}
    setmetatable(o, {__index = self})
    return o
end

--重定义
function Triangle:caculateS()
    self.S = self.bottom * self.height / 2
end

triangle = Triangle:new{name = "Triangle", bottom = 2, height = 3}

triangle:caculateS()
print("tri:", triangle.S)